package com.fs.base.controller;

import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import lombok.Getter;
import lombok.Setter;

import org.apache.commons.lang3.StringUtils;
import org.apache.log4j.Logger;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.core.io.FileSystemResource;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Sort;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.multipart.MultipartFile;
import org.springframework.web.servlet.View;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.alibaba.fastjson.serializer.PropertyFilter;
import com.fs.base.annotation.Echo;
import com.fs.base.excel.ExcelOptions;
import com.fs.base.excel.ExcelUtils;
import com.fs.base.excel.view.XlsView;
import com.fs.base.excel.view.XlsxStreamingView;
import com.fs.base.jpa.interf.QueryOpt;
import com.fs.base.jpa.specification.Criteria;
import com.fs.base.param.SysConstant;
import com.fs.base.pojo.Attachment;
import com.fs.base.pojo.PkEntity;
import com.fs.base.pojo.User;
import com.fs.base.repository.AttachmentRepository;
import com.fs.base.service.BaseService;
import com.fs.base.utils.ApplicationUtils;
import com.fs.base.utils.DateUtils;
import com.fs.base.utils.JsonUtils;
import com.fs.base.utils.Md5Utils;
import com.fs.base.utils.ModleTools;
import com.fs.base.utils.PageHeper;
import com.fs.base.vo.Combobox;
import com.fs.base.vo.Combotree;
import com.fs.base.vo.DataGrid;
import com.fs.base.vo.JsonResponse;
import com.fs.base.vo.SysPath;

/**
 * @author TiddlerCJ
 * @desc 基础通用业务处理器，此类不允许私自更改，如若需要修正，请先内部沟通讨论(注意！注意！注意！)
 */
@Controller
@RequestMapping(SysPath.BACK_PATH)
public class BaseController {
	@Getter @Setter @Value("${layui.upload.path}")
    private String layuiUploadPath;
	
	private static final Logger log = Logger.getLogger(BaseController.class); 

	@Autowired private BaseService baseService;
	@Autowired private AttachmentRepository attachmentRepository;
	
	/**
	 * 通用模块首页
	 * @param modleName
	 * @return
	 */
	@GetMapping("{modleName}/index")
	public String index(@PathVariable String modleName, HttpServletRequest req) {
		Map<String, Object> data = ApplicationUtils.getRequestDatas();
		
		req.setAttribute("modleName", modleName);
		String className = SysConstant.MODLE_CLASSNAME.get(modleName);
		if(StringUtils.isBlank(className)){ className = ""; }
		req.setAttribute("className", className);
		
		//传递请求参数到目标页面
		req.setAttribute("data", data);
		
		return SysPath.BACK_PATH.concat("/"+modleName).concat("/index");
	}

	/**
	 * 通用模块预新增
	 * @param modleName
	 * @return
	 */
	@GetMapping("{modleName}/preAdd")
	public String preAdd(@PathVariable String modleName, HttpServletRequest req) {
		req.setAttribute("modleName", modleName);
		req.setAttribute("className", SysConstant.MODLE_CLASSNAME.get(modleName));
		return SysPath.BACK_PATH.concat("/"+modleName).concat("/add");
	}

	/**
	 * 通用模块预编辑
	 * @param modleName
	 * @return
	 */
	@GetMapping("{modleName}/preModify")
	public String preModify(@PathVariable String modleName, HttpServletRequest req) {
		req.setAttribute("modleName", modleName);
		req.setAttribute("className", SysConstant.MODLE_CLASSNAME.get(modleName));
		
		return SysPath.BACK_PATH.concat("/"+modleName).concat("/modify");
	}

	/**
	 * 通用模块查看
	 * @param modleName
	 * @return
	 */
	@GetMapping("{modleName}/view")
	public String view(@PathVariable String modleName, HttpServletRequest req) {
		req.setAttribute("modleName", modleName);
		req.setAttribute("className", SysConstant.MODLE_CLASSNAME.get(modleName));
		
		return SysPath.BACK_PATH.concat("/"+modleName).concat("/view");
	}

	/**
	 * 通用模块配置
	 * @param modleName
	 * @return
	 */
	@GetMapping("{modleName}/config")
	public String configGet(@PathVariable String modleName, HttpServletRequest req) {
		req.setAttribute("modleName", modleName);
		req.setAttribute("className", SysConstant.MODLE_CLASSNAME.get(modleName));
		
		return SysPath.BACK_PATH.concat("/"+modleName).concat("/config");
	}
	
	/**
	 * 通用导入页面
	 * @param modleName
	 * @param req
	 * @return
	 */
	@GetMapping("{modleName}/import")
	public String batchImport(@PathVariable String modleName, HttpServletRequest req) {
		return SysPath.BACK_PATH.concat("/"+modleName).concat("/import");
	}
	
	/**
	 * 通用选择页面
	 * @param modleName
	 * @return
	 */
	@GetMapping("{modleName}/choosebox")
	public String choosebox(@PathVariable String modleName, HttpServletRequest req) {
		req.setAttribute("modleName", modleName);
		req.setAttribute("className", SysConstant.MODLE_CLASSNAME.get(modleName));
		return SysPath.BACK_PATH.concat("/choosebox/"+modleName);
	}
	
	/**
	 * 通用选择窗口
	 * @param modleName
	 * @return
	 */
	@GetMapping("{modleName}/chooseWin")
	public String chooseWin(@PathVariable String modleName,HttpServletRequest req){
		req.setAttribute("modleName", modleName);
		req.setAttribute("className", SysConstant.MODLE_CLASSNAME.get(modleName));
		return SysPath.BACK_PATH.concat("/chooseWin/"+modleName);
	}
	
	/**
	 * 通用模块分页查询
	 * @param className
	 * @param request
	 * @return
	 */
	@ResponseBody
	@RequestMapping("{className}/list")
	public Object list(DataGrid grid,@PathVariable String className,HttpServletRequest request) {
		try {
			if(grid==null) grid = new DataGrid();
			Page<Object> page = null;
			Map<String, Object> data = ApplicationUtils.getRequestDatas();
			//System.out.println(data);
			/*
			 * 启用业务模块数据过滤配置
			}*/
			/*if(data.containsKey(SysConstant.RIGHT_CONTROL)){
				LoginUser uVo = ApplicationUtils.LoginUser();
				int dataRight =uVo.getDataRight();
				if(dataRight==1){
					//1.查看自己发布的数据
					data.put("createrId", ApplicationUtils.userId());
					data.put("createrId_searchType", "eq");
				}else if(dataRight>1 && dataRight<=4){
					//查看部门数据
					data.put("department", uVo.getDepartments());
					data.put("department_searchType", "in");
				}else{
					//超级管理员或所有数据权限查看所有
					//查询所有数据
				}
			}*/
			Criteria<Object> c = new Criteria<Object>().addAuto(data);
			
			//树形
			if (grid.getIsTreeGrid()) {
				List<Object> list = baseService.findAllWithSort(className, request, c);
				grid = DataGrid.treeBuilder(list,grid);
			} 
			//普通表格
			else {
				if(PageHeper.isPage(request)){
					page = baseService.page(className, request, c);
					grid = DataGrid.gridBuilder(page);
				}else{
					List<Object> rows = baseService.findAllWithSort(className, request, c);
					grid = DataGrid.gridBuilder(rows);
				}
			}
		} catch (Exception e) {
			grid = DataGrid.gridBuilder(new ArrayList<Object>());
			e.printStackTrace();
			log.error(e.getMessage());
		}
		return grid;
	}

	/**
	 * 通用模块新增
	 * @param className
	 * @param request
	 * @return
	 */
	@ResponseBody
	@RequestMapping("{className}/newAdd")
	public JsonResponse newAdd(@PathVariable String className, HttpServletRequest request) {
		try {
			Map<String, Object> map = ApplicationUtils.getRequestDatas();
			Object vo = Class.forName(className).newInstance();
			/*
			 * 用户密码特殊处理
			 */
			if(vo instanceof User){
				Object pwd = map.get("pwd");
				if(pwd!=null){
					map.put("pwd", Md5Utils.md5(pwd.toString()));
				}
			}
			String json = JSON.toJSONString(map);
			vo = JSON.parseObject(json, vo.getClass());
			baseService.beanRepository(className).save(vo);
			return JsonResponse.success();
		} catch (Exception e) {
			e.printStackTrace();
			log.error(e.getMessage());
			return JsonResponse.error(e.getMessage());
		}
	}

	/**
	 * 通用模块编辑
	 * @param className
	 * @param request
	 * @return
	 */
	@ResponseBody
	@RequestMapping("{className}/modify")
	public JsonResponse modify(@PathVariable String className, HttpServletRequest request) {
		try {
			Map<String, Object> map = ApplicationUtils.getRequestDatas();
			/*
			 *忽略属性，多个值用,号分隔如：menuName,menuIcon,menuOrder 
			 */
			String[] ignoreProperties = null; 
			String ignore = request.getParameter("ignoreProperties");
			if(StringUtils.isNotBlank(ignore)){
				ignoreProperties = ignore.split(",");
				for(String temp: ignoreProperties){
					map.remove(temp);
				}
			}
			
			
			Object oldVo = baseService.beanRepository(className).findOne(map.get(PkEntity.PRIMARY_KEY_NAME).toString());
			String oldJson = JSON.toJSONString(oldVo);
			@SuppressWarnings("unchecked")
			Map<String, Object> oldMap = JSON.parseObject(oldJson, Map.class);
			oldMap.putAll(map);
			
			/*
			 * 用户密码特殊处理
			 */
			/*if(oldVo instanceof User){
				Object pwd = oldMap.get("pwd");
				if(pwd!=null){
					oldMap.put("pwd", Md5Utils.md5(pwd.toString()));
				}
			}*/
			String json = JSON.toJSONString(oldMap) ;
			
			Object newVo = JSON.parseObject(json, oldVo.getClass());
			
			
			baseService.beanRepository(className).save(newVo);
			return JsonResponse.success();
		} catch (Exception e) {
			e.printStackTrace();
			log.error(e.getMessage());
			return JsonResponse.error(e.getMessage());
		}
	}

	/**
	 * 通用删除
	 * @param className
	 * @param id
	 * @return
	 */
	@GetMapping("{className}/delete/{id}")
	@ResponseBody
	public JsonResponse deleteA(@PathVariable String className, @PathVariable String id) {
		try {
			baseService.beanRepository(className).delete(id);
			return JsonResponse.success();
		} catch (Exception e) {
			e.printStackTrace();
			log.error(e.getMessage());
			return JsonResponse.error(e.getMessage());
		}
	}

	/**
	 * 通用删除，delete by id or grid rows
	 * @param className
	 */
	@GetMapping("{className}/delete")
	@ResponseBody
	public JsonResponse deleteB(@PathVariable String className, HttpServletRequest request) {
		try {
			String id = request.getParameter(PkEntity.PRIMARY_KEY_NAME);
			if (StringUtils.isNotBlank(id)) {
				String[] ids = id.split(",");
				for (String key : ids) {
					baseService.beanRepository(className).delete(key);
				}
			}
			String rows = request.getParameter("rows");
			if (StringUtils.isNotBlank(rows)) {
				JSONObject item = null;
				JSONArray array = JSONArray.parseArray(rows);
				for (int i = 0, len = array.size(); i < len; i++) {
					item = array.getJSONObject(i);
					if (item.containsKey(PkEntity.PRIMARY_KEY_NAME)) {
						baseService.beanRepository(className).delete(item.getString(PkEntity.PRIMARY_KEY_NAME));
					}
				}
			}
			return JsonResponse.success();
		} catch (Exception e) {
			e.printStackTrace();
			log.error(e.getMessage());
			return JsonResponse.error(e.getMessage());
		}
	}
	
	/**
	 * @desc 返回实体拼接字符串以#分割
	 * @param className
	 * @param fieldIdName
	 * @param request
	 * @return
	 * 调用示例：
	 * 	var param = { userId : fn.data.id ,userId_searchType:'eq' };
 		var url = "/console/com.fs.base.pojo.UserRole/getFieldIds/roleId";
 	 *	$.getJSON(url, param ,function(roleIds){
 	 *		roleIds = roleIds.join(",");
 	 *		//do something ...
 	 *	});
	 * 
	 * 
	 */
	@ResponseBody
	@RequestMapping("{className}/getFieldIds/{fieldIdName}")
	public List<Object> getUserRoles(@PathVariable String className, @PathVariable String fieldIdName, HttpServletRequest request) {
		List<Object> result = new ArrayList<Object>();
		try {
			if(StringUtils.isNotBlank(className) && StringUtils.isNotBlank(fieldIdName)){
				Map<String, Object> data = ApplicationUtils.getRequestDatas();
				Criteria<Object> c = new Criteria<Object>().addAuto(data);
				List<Object> list = baseService.beanSpecification(className).findAll(c);
				JSONObject json = null;
				for(Object obj: list){
					json = (JSONObject) JSON.toJSON(obj);
					result.add(json.get(fieldIdName));
				}
			}
		} catch (Exception e) {
			e.printStackTrace();
			log.error(e.getMessage());
		}
		return result;
	}
	
	/**
	 * @param className
	 * @param valueField
	 * @param textField
	 * @param defaultValue
	 * eg1:http://localhost/console/com.fs.base.pojo.Dictionary/combobox
	 * eg2:http://localhost/console/com.fs.base.pojo.Dictionary/combobox?valueField=id&textField=dicName
	 * eg3:http://localhost/console/combobox?valueField=id&textField=dicCode&modleName=dictionary&text=0000&attributes=dicValue,pCode
	 * @return
	 */
	@ResponseBody
	@RequestMapping("{className}/combobox")
	public Object comboboxA(Combobox combobox ,@PathVariable String className, HttpServletRequest req){
		try {
			if(StringUtils.isNotBlank(className)){
				if(combobox==null) combobox = new Combobox();
				combobox.setClassName(className);
				
				Map<String, Object> data = ApplicationUtils.getRequestDatas();
				/*
				 * 添加排序
				 */
				Sort sort = PageHeper.sort(req);
				
				Criteria<Object> c = new Criteria<Object>().addAuto(data);
				List<Object> list = baseService.beanSpecification(className).findAll(c,sort);
				combobox = Combobox.builder(list, combobox);
			}
		} catch (Exception e) {
			e.printStackTrace();
			log.error(e.getMessage());
		}
		return combobox.getData();
	}
	
	/**
	 * @param modleName
	 * eg1:http://localhost/console/combobox?valueField=id&textField=dicName&modleName=dictionary
	 * eg2:http://localhost/console/combobox?valueField=id&textField=dicName&modleName=dictionary&defaultText=xxxText
	 * @return
	 */
	@ResponseBody
	@RequestMapping("combobox")
	public Object comboboxB(Combobox combobox ,String modleName,HttpServletRequest req){
		String className = SysConstant.MODLE_CLASSNAME.get(modleName);
		return comboboxA(combobox ,className, req);
	}
	
	/**
	 * @desc combotree控件数据接口 idField默认为id
	 * @param modleName
	 * @param req
	 * @return
	 * @eq1 http://localhost/console/dictionary/combotree?idField=id&pidField=parentId&textField=dicName&textOrValues=402881e45b38dd9f015b38e6fc6b0009
	 * @eq2 http://localhost/console/dictionary/combotree?pidField=parentId&textField=dicName&textOrValues=402881e45b38dd9f015b38e6fc6b0009
	 */
	@ResponseBody
	@RequestMapping("{modleName}/combotree")
	public Object combotree(Combotree combotree,@PathVariable String modleName, HttpServletRequest req){
		try {
			if(StringUtils.isNotBlank(modleName)){
				String className = SysConstant.MODLE_CLASSNAME.get(modleName);
				if(StringUtils.isNotBlank(className)){
					Map<String, Object> data = ApplicationUtils.getRequestDatas();
					Criteria<Object> c = new Criteria<Object>().addAuto(data);
					List<Object> list = baseService.beanSpecification(className).findAll(c);
					combotree = Combotree.builder(list, combotree);
				}
			}
		} catch (Exception e) {
			e.printStackTrace();
			log.error(e.getMessage());
		}
		return combotree.getData();
	}
	
	/**
	 * 数据回显
	 * @param modleName
	 * @return
	 */
	@ResponseBody
	@RequestMapping("{modleName}/echo")
	public Object echo(@PathVariable String modleName,String echoValue){
		Echo echo = null;
		List<Object> echoList = new ArrayList<Object>();
		String textField = "" ,  idField = "";
		Map<String, Object> requestData = ApplicationUtils.getRequestDatas();
		try {
			if(StringUtils.isNotBlank(modleName)){
				String className = SysConstant.MODLE_CLASSNAME.get(modleName);
				Map<String, Object> data = new HashMap<String, Object>();
				echo = (Echo) ModleTools.getAnnotationByName(className, Echo.class);
				if(echo!=null){
					idField = echo.idField();
					textField = echo.textField();
				}
				
				if(requestData!=null){
					if(requestData.containsKey("idField")){
						idField = requestData.get("idField").toString();
					}
					if(requestData.containsKey("textField")){
						textField = requestData.get("textField").toString();
					}
				}
				
				if(StringUtils.isNotBlank(idField) && StringUtils.isNotBlank(textField)){
					data.put(idField, echoValue);
					data.put(idField.concat(QueryOpt.QUERY_POSTFIX), "in");
					
					Criteria<Object> c = new Criteria<Object>().addAuto(data);
					echoList = baseService.beanSpecification(className).findAll(c);
				}
			}
		} catch (Exception e) {
			e.printStackTrace();
			log.error(e.getMessage());
		}
		
		Map<String, String> fieldsMap = new HashMap<String, String>();
		fieldsMap.put(textField, textField);
		fieldsMap.put(idField, idField);
		
		PropertyFilter filter = JsonUtils.filter(fieldsMap);
		
		String json = JSON.toJSONString(echoList, filter);
		
		return JSON.parse(json);
		/*SerializeFilter[] filters = new SerializeFilter[]{ 
				PropertyFilter.getIncludeFilter(new String[]{ textField, idField }) 
		} ;*/
		//return JsonUtils.getFastJsonData(echoList, filters);
		
	}
	/**
	 * 数据唯一验证
	 * @param modleName
	 * @param original 
	 * @return
	 * 调用方式如：data-options="label:'唯一验证:',required:true,validType:'remote[\'/console/user/remote\',\'account\']' " 
	 */
	@ResponseBody
	@RequestMapping("{modleName}/remote")
	public Boolean remote(@PathVariable String modleName,String paramName,String original){
   		Boolean flag = true;
		try {
			Map<String, Object> data = ApplicationUtils.getRequestDatas();
			if(StringUtils.isNotBlank(modleName) && StringUtils.isNotBlank(paramName)){
				Object value = data.get(paramName);
				if(value instanceof String){
					value = value.toString().trim();
					//if(value.equals(original)) return true;
				}
				data.put(paramName, value);
				data.put(paramName.concat("_searchType"),"eq");
				String className = SysConstant.MODLE_CLASSNAME.get(modleName);
				Criteria<Object> c = new Criteria<Object>().addAuto(data);
				List<Object> result = baseService.beanSpecification(className).findAll(c);
				if(result.size()>0){
					flag = false;
				}
			}
		} catch (Exception e) {
			e.printStackTrace();
			log.error(e.getMessage());
		}
		return flag;
	}
	
	/**
	 * 自动编码
	 * @param modleName
	 * @return
	 */
	@ResponseBody
	@RequestMapping("{prefix}/autoCode") 
	public JsonResponse autoCode(@PathVariable String prefix,String suffix,String timestamp){
		JSONObject attrs = new JSONObject();
		try {
			String autoCode  = "";
			if(StringUtils.isBlank(timestamp)){
				timestamp = "yyMMddHHmmssSSS";
			}
			if(StringUtils.isNotBlank(prefix)){
				autoCode += prefix.concat(DateUtils.curDate(timestamp));
			}else{
				autoCode += DateUtils.curDate(timestamp) ;
			}
			if(StringUtils.isNotBlank(suffix)){
				autoCode += suffix ;
				attrs.put("suffix", suffix);
			}
			attrs.put("code", autoCode);
			attrs.put("prefix", prefix);
			
			return JsonResponse.success(attrs);
		} catch (Exception e) {
			e.printStackTrace();
			log.error(e.getMessage());
			return JsonResponse.error(e.getMessage());
		}
	}
	
	/**
	 * layui通用上传
	 * @param file
	 * @return
	 */
	@ResponseBody
	@RequestMapping("layui/upload")
	public JsonResponse upload(MultipartFile file){
		JSONObject attrs = new JSONObject();
		try {
			if (file.isEmpty()) {
				JsonResponse.error("文件为空");
			}else{
				// 获取文件名
				String original = file.getOriginalFilename();
				// 获取文件的后缀名
				String suffixName = original.substring(original.lastIndexOf("."));
				
				String newName = System.currentTimeMillis() + suffixName;
				String filePath = layuiUploadPath.concat(newName);
				
				File dest = new File(filePath);
				long size = file.getSize();
				
				// 检测是否存在目录
				if (!dest.getParentFile().exists()) {
					dest.getParentFile().mkdirs();
				}
				file.transferTo(dest);
				String createrId = ApplicationUtils.userId();
				if(dest.exists()){
					Attachment att = new Attachment(ApplicationUtils.userId(), newName, original, "SUCCESS", suffixName, filePath, size);
					att.setCreaterId(createrId);
					baseService.beanRepository(Attachment.class).save(att);
					attrs =(JSONObject) JSON.toJSON(att);
				}
			}
			return JsonResponse.success(attrs);
		} catch (Exception e) {
			e.printStackTrace();
			log.error(e.getMessage());
			return JsonResponse.error(e.getMessage());
		}
	}
	
	/*
	 * 上传附件删除
	 */
	@ResponseBody
	@RequestMapping("layui/upload/delete")
	public JsonResponse uploadDelete(String id){
		try {
			if(StringUtils.isNotBlank(id)){
				// 删除数据库记录并删除文件
				Object att = baseService.beanRepository(Attachment.class).findOne(id);
				baseService.beanRepository(Attachment.class).delete(id);
				
				JSONObject json = (JSONObject)JSON.toJSON(att);
				String path = json.getString("url");
				File file = new File(path);
				if(file.exists()){
					file.delete();
				} 
			}
			return JsonResponse.success();
		} catch (Exception e) {
			e.printStackTrace();
			log.error(e.getMessage());
			return JsonResponse.error(e.getMessage());
		}
	}
	
	/*
	 * 上传附件回显
	 */
	@ResponseBody
	@RequestMapping("layui/upload/list")
	public JSONArray uploadList(String ids){
		List<Object> result = new ArrayList<Object>();
		try {
			if(StringUtils.isNotBlank(ids)){
				String[] idArray = ids.split(",");
				List<String> list = Arrays.asList(idArray);
				Criteria<Object> c = new Criteria<Object>().addIn("id", list);
				result = baseService.beanSpecification(Attachment.class).findAll(c);
			}
			return (JSONArray)JSON.toJSON(result);
		} catch (Exception e) {
			e.printStackTrace();
			log.error(e.getMessage());
			return new JSONArray();
		}
	}
	
	/**
	 * 导出excel
	 * local:true 时读取页面缓存数据
	 */
	@RequestMapping(value = "{className}/export")
	public View export(HttpServletRequest request, HttpServletResponse response, @PathVariable String className) {
		XlsView view = null;
		try {
			ExcelOptions opts = ExcelUtils.getOptions(request);
			//System.out.println(JSON.toJSONString(opts));
			String fileName = StringUtils.trimToEmpty(opts.getFilename());
			List<Object> list = new ArrayList<Object>();
			
			if(!opts.isLocal()){
				Map<String, Object> data = ApplicationUtils.getRequestDatas();
				Criteria<Object> c = new Criteria<Object>().addAuto(data);
				list = baseService.findAllWithSort(className, request, c);
			}else{
				list = opts.getData();
			}
			if (StringUtils.endsWithIgnoreCase(fileName, ".xlsx")) view = new XlsxStreamingView(list);
			else view = new XlsView(list);
			view.setOpts(opts);
		} catch (Exception e) {
			log.error(e.getMessage(), e);
		}
		return view;
	}
	
	
	@ResponseBody
	@RequestMapping("{className}/jsonArray")
	public Object jsonArray(DataGrid grid,@PathVariable String className,HttpServletRequest request) {
		try {
			if(grid==null) grid = new DataGrid();
			Page<Object> page = null;
			Map<String, Object> data = ApplicationUtils.getRequestDatas();
			Criteria<Object> c = new Criteria<Object>().addAuto(data);
			if(PageHeper.isPage(request)){
				page = baseService.page(className, request, c);
				grid = DataGrid.gridBuilder(page);
			}else{
				List<Object> rows = baseService.findAllWithSort(className, request, c);
				grid = DataGrid.gridBuilder(rows);
			}
		} catch (Exception e) {
			grid = DataGrid.gridBuilder(new ArrayList<Object>());
			e.printStackTrace();
			log.error(e.getMessage());
		}
		return grid;
	}
	
	@ResponseBody
	@RequestMapping("{className}/json")
	public Object json(@PathVariable String className,HttpServletRequest request) {
		Object obj = new Object();
		try {
			Map<String, Object> data = ApplicationUtils.getRequestDatas();
			Criteria<Object> c = new Criteria<Object>().addAuto(data);
			List<Object> rows = baseService.findAllWithSort(className, request, c);
			if(rows!=null && rows.size()>0){
				obj= rows.get(0);
			}
		} catch (Exception e) {
			e.printStackTrace();
			log.error(e.getMessage());
		}
		return obj;
	}
	
	@ResponseBody
	@RequestMapping("userName")
	public String userName(String id,HttpServletRequest request) {
		return SysConstant.USERS_ID_NAME_MAP.get(id);
	}
	
	@RequestMapping("/download")  
	public ResponseEntity<byte[]> downloadFile(String id,HttpServletRequest request) throws IOException {
       byte[] body = null;  
       ResponseEntity<byte[]> response = null;
       Attachment attachment = attachmentRepository.findOne(id);
       if(attachment!=null){
    	   String filePath =  attachment.getUrl();
			FileSystemResource file = new FileSystemResource(filePath);
			
			if(!file.exists()){
				File tempFile = new File(filePath);
				tempFile.createNewFile();
				file = new FileSystemResource(filePath);
				attachment.setOriginal("此文件已丢失");
			}
			
			InputStream in = file.getInputStream();
			body = new byte[in.available()];
		    in.read(body);
		    
		    String filedisplay = attachment.getOriginal();
		    String userAgent = request.getHeader("User-Agent");
		    if(userAgent.contains("MSIE")||userAgent.contains("Trident")) {
		        filedisplay = java.net.URLEncoder.encode(filedisplay, "UTF-8");
		    }else {
		        //非IE浏览器的处理：
		        filedisplay = new String(filedisplay.getBytes("UTF-8"),"ISO-8859-1");
		    }
		    HttpHeaders headers = new HttpHeaders();  
		    headers.add("Cache-Control", "no-cache, no-store, must-revalidate");  
			headers.add("Content-Disposition","attachment;filename=" + filedisplay);  
			headers.add("Pragma", "no-cache");
			headers.add("Expires", "0");
		    HttpStatus statusCode=HttpStatus.OK;  
		    response=new ResponseEntity<byte[]>(body,headers,statusCode);  
       }
       return response;  
   }
	
	/**
	 * 通用页面跳转
	 * @param pageName
	 * @param req
	 * @return
	 */
	@RequestMapping("/page")
	public String page(String pageName, HttpServletRequest req){
		return SysPath.BACK_PATH.concat("/").concat(pageName);
	}
}
